/*
// 所需的参数

// 对象名称
#define xarg_name

// 字段 0 名称
#define xarg_a0

// 字段 1 名称
#define xarg_a1

// 字段 2 名称
#define xarg_a2
*/

#ifndef xarg_name
#error "missing xarg_name"
#endif

#ifndef xarg_a0
#error "missing xarg_a0"
#endif

#ifndef xarg_a1
#error "missing xarg_a1"
#endif

#ifndef xarg_a2
#error "missing xarg_a2"
#endif

#define xmember2(name)          m_ ## name
#define xmember(name)           xmember2(name)

#include"macro/xlink.hpp"

template<class posx_t, class posy_t = posx_t, class posz_t = void>
xstruct(
    xtmpl(xarg_name, posx_t, posy_t, posz_t),
    xprif(xmember(xarg_a0), posx_t),
    xprif(xmember(xarg_a1), posy_t),
    xprif(xmember(xarg_a2), posz_t)
) 
public:
    xprops()
        xpubget_pubset(xarg_a0, posx_t);
        xpubget_pubset(xarg_a1, posy_t);
        xpubget_pubset(xarg_a2, posz_t);
    $

    xprops_operator()
public:
    constexpr xarg_name() : 
        xarg_name(0, 0, 0){
    }

    constexpr xarg_name(posx_t xarg_a0, posy_t xarg_a1, posz_t xarg_a2):
        xmember(xarg_a0)(xarg_a0),
        xmember(xarg_a1)(xarg_a1),
        xmember(xarg_a2)(xarg_a2){
    }

    constexpr xarg_name(xarg_name<posx_t, posy_t, posz_t> const &) = default;

    the_t operator()(posx_t xarg_a0, posy_t xarg_a1, posz_t xarg_a2){
        return the_t(xmember(xarg_a0) + xarg_a0, xmember(xarg_a1) + xarg_a1, xmember(xarg_a2) + xarg_a2);
    }

    the_t operator - (the_t const & p){
        return xthe(posx_t(0) - p->xarg_a0(), posx_t(0) - p->xarg_a1(), posx_t(0) - p->xarg_a2());
    }

    the_t operator + (the_t const & p){
        return xthe(p->xarg_a0(), p->xarg_a1(), p->xarg_a2());
    }

    the_t & operator -= (the_t const & p){
        xthe = xthe - p;
        return xthe;
    }

    the_t & operator += (the_t const & p){
        xthe = xthe + p;
        return xthe;
    }
$

template<class posx_t, class posy_t>
xstruct(
    xspec(xarg_name, posx_t, posy_t, void),
    xprif(xmember(xarg_a0), posx_t),
    xprif(xmember(xarg_a1), posy_t)
) 
public:
    xprops()
        xpubget_pubset(xarg_a0, posx_t);
        xpubget_pubset(xarg_a1, posy_t);
    $

    xprops_operator()
public:
    constexpr xarg_name() : 
        xarg_name(0, 0){
    }

    constexpr xarg_name(posx_t xarg_a0, posy_t xarg_a1):
        xmember(xarg_a0)(xarg_a0), xmember(xarg_a1)(xarg_a1){
    }

    the_t operator()(posx_t xarg_a0, posy_t xarg_a1){
        return the_t(xmember(xarg_a0) + xarg_a0, xmember(xarg_a1) + xarg_a1);
    }

    the_t operator - (the_t const & p){
        return xthe(posx_t(0) - p->xarg_a0(), posx_t(0) - p->xarg_a1());
    }

    the_t operator + (the_t const & p){
        return xthe(p->xarg_a0(), p->xarg_a1());
    }

    the_t & operator -= (the_t const & p){
        xthe = xthe - p;
        return xthe;
    }

    the_t & operator += (the_t const & p){
        xthe = xthe + p;
        return xthe;
    }
$

#undef  xarg_name
#undef  xarg_a0
#undef  xarg_a1
#undef  xarg_a2
#undef  xmember
#undef  xmember2
